package momo.multitree.simulation;

import java.io.FileReader;
import java.util.Collections;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import momo.multitree.structure.Edge;
import momo.multitree.structure.Graph;
import momo.multitree.structure.Node;
import momo.multitree.structure.Tree;

public class OptStarTree extends TreeOptAlg {
	
	private Log log = LogFactory.getLog(OptStarTree.class);
	
	private Set<Tree> starTrees;

	public OptStarTree(Graph g) {
		super(g);
		this.starTrees = new HashSet<Tree>();
		this.initStarTree();
	}
	
	private void initStarTree() {
		boolean firstTree = true;
		Set<Node> set = g.getNodes();
		int totalNodes = g.getNoOfNodes();
		for (Node node: set) {
			Set<Edge> edgeSet = g.getEdgesOfNode(node);
			int totalEdges = edgeSet.size();
			if ( totalEdges == (totalNodes-1) ) {
				//create star tree
				Tree newTree = new Tree(node);
				for ( Edge edge : edgeSet )
					newTree.add(edge);
				starTrees.add(newTree);
				if ( firstTree ) {
					initBestTree = newTree;
					firstTree = false;
				}
			}
		}
	}
	
	public boolean isStarTopologyExist() {
		return starTrees.size()>0?true:false;
	}
	
	public int getTotalStarTopologyExist() {
		return starTrees.size();
	}
	
	public void printStar() {
		for (Tree tree : starTrees) {
			System.out.println( tree.toString() );
		}
	}

	public Tree optimizeTree() {
		if ( !isStarTopologyExist() )
			return null;
		else {
			Tree bestTree = initBestTree;
			double dist = scoreLen(initBestTree);
			for ( Tree tree: starTrees ) {
				double newDist = scoreLen(tree);
				if ( newDist < dist )
					bestTree = tree;
			}
			return bestTree;
		}
	}
	
	public Set<Tree> getAllPossibleStarTree() {
		return Collections.unmodifiableSet(this.starTrees);
	}
}
